import { LoginInfo } from '@/models/system';
import { Op } from 'sequelize';
import sequelize from '@/config/database';
import DateUtil from '@/utils/javaScript/date.util';
import { getLogger } from '@/utils/logger';

const logger = getLogger("loginInfo-service", {
  console: false,
});
const consoleLogger = getLogger("loginInfo-service");

/**
 * 系统访问日志情况信息 服务层
 */
class LoginInfoService {
  /**
   * 新增系统登录日志
   * @param loginInfo 访问日志对象
   */
  public async insertLoginInfo(loginInfo: any): Promise<void> {
    try {
      // 使用consoleLogger记录操作开始
      consoleLogger.info(`新增登录日志: userName=${loginInfo.userName}, ipaddr=${loginInfo.ipaddr}`);
      
      // 如果没有设置登录时间，设置为当前时间
      if (!loginInfo.loginTime) {
        loginInfo.loginTime = new Date();
      }
      
      const result = await LoginInfo.create(loginInfo);
      
      // 记录操作结果
      logger.info(`登录日志新增成功: infoId=${result.infoId}, userName=${loginInfo.userName}`);
    } catch (error) {
      consoleLogger.error(`新增登录日志失败: ${error instanceof Error ? error.message : String(error)}`);
      throw new Error('新增登录日志失败');
    }
  }

  /**
   * 查询系统登录日志集合
   * @param loginInfo 访问日志对象
   * @returns 登录记录集合
   */
  public async selectLoginInfoList(loginInfo: any): Promise<LoginInfo[]> {
    try {
      // 使用consoleLogger记录操作开始
      consoleLogger.info(`查询登录日志列表: ${JSON.stringify(loginInfo)}`);
      
      const condition: any = {};
      
      // 构建查询条件
      if (loginInfo.ipaddr) {
        condition.ipaddr = { [Op.like]: `%${loginInfo.ipaddr}%` };
      }
      
      if (loginInfo.userName) {
        condition.userName = { [Op.like]: `%${loginInfo.userName}%` };
      }
      
      if (loginInfo.status !== undefined && loginInfo.status !== null && loginInfo.status !== '') {
        condition.status = loginInfo.status;
      }
      
      // 时间范围查询
      if (loginInfo.params && loginInfo.params.beginTime && loginInfo.params.endTime) {
        const beginDate = DateUtil.parseDate(loginInfo.params.beginTime);
        const endDate = DateUtil.parseDate(loginInfo.params.endTime);
        
        if (beginDate && endDate) {
          // 设置结束日期为当天的23:59:59
          endDate.setHours(23, 59, 59);
          
          condition.loginTime = { 
            [Op.between]: [beginDate, endDate] 
          };
          
          logger.debug(`设置时间范围查询: ${beginDate.toISOString()} 至 ${endDate.toISOString()}`);
        }
      }

      // 排序
      const order: any[] = [];
      if (loginInfo.orderByColumn && loginInfo.isAsc) {
        const sortOrder = loginInfo.isAsc === 'ascend' ? 'ASC' : 'DESC';
        
        // 转换前端字段名称为数据库字段名称
        let columnName = loginInfo.orderByColumn;
        if (columnName === 'userName') columnName = 'user_name';
        else if (columnName === 'loginTime') columnName = 'login_time';
        
        order.push([columnName, sortOrder]);
        logger.debug(`设置排序: ${columnName} ${sortOrder}`);
      } else {
        // 默认按照访问时间倒序排列
        order.push(['login_time', 'DESC']);
      }

      const results = await LoginInfo.findAll({
        where: condition,
        order
      });
      
      // 记录查询结果
      logger.info(`登录日志查询完成: 总数=${results.length}`);
      
      return results;
    } catch (error) {
      consoleLogger.error(`查询登录日志列表失败: ${error instanceof Error ? error.message : String(error)}`);
      throw new Error('查询登录日志失败');
    }
  }

  /**
   * 批量删除系统登录日志
   * @param infoIds 需要删除的登录日志ID
   * @returns 结果
   */
  public async deleteLoginInfoByIds(infoIds: number[]): Promise<number> {
    try {
      // 使用consoleLogger记录操作开始
      consoleLogger.info(`批量删除登录日志: infoIds=${JSON.stringify(infoIds)}`);
      
      if (!infoIds || infoIds.length === 0) {
        consoleLogger.error('批量删除登录日志失败: 参数为空');
        throw new Error('登录日志ID不能为空');
      }
      
      const result = await LoginInfo.destroy({
        where: {
          infoId: {
            [Op.in]: infoIds
          }
        }
      });
      
      // 记录操作结果
      logger.info(`登录日志批量删除完成: 删除项数量=${infoIds.length}, 影响行数=${result}`);
      
      return result;
    } catch (error) {
      consoleLogger.error(`批量删除登录日志失败: ${error instanceof Error ? error.message : String(error)}`);
      throw new Error('批量删除登录日志失败');
    }
  }

  /**
   * 清空系统登录日志
   */
  public async cleanLoginInfo(): Promise<void> {
    try {
      // 使用consoleLogger记录操作开始
      consoleLogger.info('清空登录日志');
      
      await LoginInfo.destroy({
        where: {},
        truncate: true
      });
      
      // 记录操作结果
      logger.info('登录日志清空完成');
    } catch (error) {
      consoleLogger.error(`清空登录日志失败: ${error instanceof Error ? error.message : String(error)}`);
      throw new Error('清空登录日志失败');
    }
  }

  /**
   * 查询系统登录日志详细
   * @param infoId 登录ID
   * @returns 登录日志对象
   */
  public async selectLoginInfoById(infoId: number): Promise<LoginInfo | null> {
    try {
      // 使用consoleLogger记录操作开始
      consoleLogger.info(`根据ID查询登录日志: infoId=${infoId}`);
      
      // 检查infoId是否有效
      if (isNaN(infoId)) {
        consoleLogger.error(`根据ID查询登录日志失败: infoId "${infoId}" 不是有效的数字`);
        throw new Error('无效的登录日志ID');
      }
      
      const loginInfo = await LoginInfo.findByPk(infoId);
      
      // 记录查询结果
      if (loginInfo) {
        logger.info(`登录日志查询成功: infoId=${infoId}, userName=${loginInfo.userName}`);
      } else {
        logger.info(`未找到登录日志: infoId=${infoId}`);
      }
      
      return loginInfo;
    } catch (error) {
      consoleLogger.error(`根据ID查询登录日志失败: ${error instanceof Error ? error.message : String(error)}`);
      throw new Error('查询登录日志详细信息失败');
    }
  }

  /**
   * 统计用户登录情况
   * @param userName 用户名
   * @param days 天数范围，默认7天
   * @returns 统计结果
   */
  public async countUserLoginInfo(userName?: string, days: number = 7): Promise<any> {
    try {
      // 使用consoleLogger记录操作开始
      consoleLogger.info(`统计用户登录信息: userName=${userName || '所有用户'}, days=${days}`);
      
      // 计算开始日期（默认7天前）
      const startDate = new Date();
      startDate.setDate(startDate.getDate() - days);
      startDate.setHours(0, 0, 0, 0);
      
      // 构建查询条件
      const condition: any = {
        loginTime: {
          [Op.gte]: startDate
        }
      };
      
      if (userName) {
        condition.userName = userName;
      }
      
      logger.debug(`统计查询条件: 开始日期=${startDate.toISOString()}, 用户名=${userName || '所有用户'}`);
      
      // 统计成功和失败的登录次数
      const successCount = await LoginInfo.count({
        where: {
          ...condition,
          status: LoginInfo.STATUS.SUCCESS
        }
      });
      
      const failCount = await LoginInfo.count({
        where: {
          ...condition,
          status: LoginInfo.STATUS.FAIL
        }
      });
      
      logger.debug(`统计结果: 成功登录=${successCount}, 失败登录=${failCount}`);
      
      // 按天统计登录次数
      // 获取最近的登录记录（按用户和时间分组）
      const loginRecords = await LoginInfo.findAll({
        where: condition,
        attributes: [
          [sequelize.fn('DATE', sequelize.col('login_time')), 'date'],
          [sequelize.fn('COUNT', sequelize.col('info_id')), 'count'],
          'status'
        ],
        group: [
          sequelize.fn('DATE', sequelize.col('login_time')),
          'status'
        ],
        order: [
          [sequelize.fn('DATE', sequelize.col('login_time')), 'ASC']
        ],
        raw: true
      });
      
      // 处理统计数据
      const dateMap = new Map();
      const dateArray: string[] = [];
      
      // 生成日期范围数组
      for (let i = 0; i < days; i++) {
        const date = new Date();
        date.setDate(date.getDate() - (days - 1 - i));
        const dateStr = DateUtil.parseDateToStr(DateUtil.YYYY_MM_DD, date);
        dateArray.push(dateStr);
        dateMap.set(dateStr, { success: 0, fail: 0 });
      }
      
      // 填充统计数据
      loginRecords.forEach((record: any) => {
        const dateStr = record.date;
        if (dateMap.has(dateStr)) {
          const data = dateMap.get(dateStr);
          if (record.status === LoginInfo.STATUS.SUCCESS) {
            data.success = parseInt(record.count);
          } else if (record.status === LoginInfo.STATUS.FAIL) {
            data.fail = parseInt(record.count);
          }
        }
      });
      
      // 组装结果数组
      const successArray: number[] = [];
      const failArray: number[] = [];
      
      dateArray.forEach(date => {
        const data = dateMap.get(date);
        successArray.push(data.success);
        failArray.push(data.fail);
      });
      
      const result = {
        total: {
          success: successCount,
          fail: failCount
        },
        dateArray,
        successArray,
        failArray
      };
      
      // 记录操作结果
      logger.info(`用户登录统计完成: 用户=${userName || '所有用户'}, 总成功次数=${successCount}, 总失败次数=${failCount}`);
      
      return result;
    } catch (error) {
      consoleLogger.error(`统计用户登录失败: ${error instanceof Error ? error.message : String(error)}`);
      throw new Error('统计用户登录情况失败');
    }
  }
}

export default new LoginInfoService(); 